// co1.cpp : Defines the entry point for the console application.
//

#include "xh_coroutine.hpp"
#include "xh_asio.hpp"

void test1()
{
	COChan<int> chan0;
	COChan<int> chan1;
	COChan<int> chan2;

	go [&]{
		int v;
		chan0 >> v;
		std::cout << "chan0 finished" << std::endl;
	};

	go [&]{
		/*
		co_select(
			chan1 >> [&] {
				int v;
				chan1 >> v;
				std::cout << "chan1 get " << v << std::endl;
			},
			chan2 >> [&] {
				int v;
				chan2 >> v;
				std::cout << "chan2 get " << v << std::endl;
			}
		);
		*/

		// test cancel
		COSelector selector;
		co_select(selector,
			chan1 >> [&] {
				int v;
				chan1 >> v;
				std::cout << "chan1 get " << v << std::endl;

				go [&] {
					selector.exit();
				};
			},
			chan2 >> [&] {
				int v;
				chan2 >> v;
				std::cout << "chan2 get " << v << std::endl;
			}
		);

		std::cout << "COReceive finished" << std::endl;
	};
	
	go [&]{
		std::cout << "11" << std::endl;
		co_yield;
		std::cout << "22" << std::endl;
		chan0 << 1000;
		chan1 << 1 << 2;
		chan2 << 3 << 4;
	};

	co_loop;
}

void test2()
{
    using namespace boost::asio::ip;

    boost::asio::io_service ioservice;
	boost::asio::io_service::work work(ioservice);

    go [&] {
        tcp::endpoint endpoint(tcp::v4(), 5000);
        auto server = std::make_shared<ASIOAcceptor>(ioservice, endpoint);
		while (true)
		{
			if (!server->accept())
			{
				std::cout << "socket accepted" << std::endl;
				auto client = server->make_accepted_connection();
				go [client] {
					char buf[10];
					while (client->is_open())
					{
						auto size = client->read_some(buf, sizeof(buf));
						client->write(buf, size);
					}
					std::cout << "client closed" << std::endl;
				};
			}
		}
	};

	go [&]{
		// std::cout << GetTickCount() << std::endl;
		ASIOUtils::sleep(ioservice, 1000);
		// std::cout << GetTickCount() << std::endl;

		tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"),5000);
		auto connector = std::make_shared<ASIOConnector>(ioservice);
		if (connector->connect(endpoint))
			return;
// 		if (connector->connect("127.0.0.1", "5000"))
// 			return;
		auto connection = connector->make_connection();

		char buf[10];
		connection->write("11111111234", 10);
		connection->read(buf, 10);
		connection->close();

		std::cout << "connector finished" << std::endl;
	};

	while (true)
	{
		co_loop_once;
		ioservice.run_one();
	}
}


int main(int argc, char* argv[])
{
	test1();
	test2();
	return 0;
}
